package pom.viz;

import java.awt.Color;
import java.awt.Rectangle;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;

import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.poi.hslf.model.AutoShape;
import org.apache.poi.hslf.model.HeadersFooters;
import org.apache.poi.hslf.model.Line;
import org.apache.poi.hslf.model.Shape;
import org.apache.poi.hslf.model.ShapeTypes;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextBox;
import org.apache.poi.hslf.model.TextShape;
import org.apache.poi.hslf.usermodel.SlideShow;

/**
 * run with mvn pom.viz:pomViz:pomViz
 * 
 *@goal pomViz
 */
public class PomVizMojo extends AbstractMojo {

	/** @parameter default-value="${project}" */
	private MavenProject mavenProject;
	SlideShow ppt = new SlideShow();
	Slide slide = ppt.createSlide();

	public void execute() throws MojoExecutionException, MojoFailureException {
		dumpPPT();

		HeadersFooters hdd = ppt.getSlideHeadersFooters();
		hdd.setSlideNumberVisible(true);
		if (mavenProject.getName() != null) {
			hdd.setFootersText("Visual POM for " + mavenProject.getName());
		}

		final TextBox pomBox = addBox(mavenProject);
		pomBox.setAnchor(new Rectangle(10, 10, 300, 36));
		//addBox(mavenProject.getParent());
		addDependencies(pomBox, mavenProject.getDependencies());

		FileOutputStream out;
		try {
			out = new FileOutputStream("slideshow.ppt");
			ppt.write(out);
			out.close();

			Runtime.getRuntime().exec("cmd /K start slideshow.ppt");
		} catch (Exception e) {
			throw new MojoExecutionException("", e);
		}
	}

	private void dumpPPT() {
		try {
			FileInputStream fis = new FileInputStream(new File("slide.ppt"));
			SlideShow p = new SlideShow(fis);
			final Shape[] shapes = p.getSlides()[0].getShapes();
			for (int i = 0; i < shapes.length; i++) {
				Shape shape = shapes[i];
				System.out.println(shape.getShapeId() + " " + shape.getShapeName() + " " + shape.getShapeType() + " " + shape.getLogicalAnchor2D());
				if (shape.getShapeType() == 33) {
					List cr = shape.getSpContainer().getChildRecords();
					for (Object o : cr) {
						System.out.println(o);
					}
					for (short j = 0; j < Short.MAX_VALUE; j++) {
						final int ep = shape.getEscherProperty(j);
						if (ep > 0) {
							System.out.println(j + " " + ep);
						}
					}
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	private void addDependencies(final TextBox pomBox, final List<Dependency> dependencies) {
		if (dependencies == null) {
			return;
		}
		int RIGHT = 20;
		int WIDHT = 200;
		int HEIGHT = 45;
		int y = 0;
		for (Dependency dependency : dependencies) {
			y += HEIGHT + 10;
			final TextBox dBox = addBox(dependency);
			dBox.setAnchor(new Rectangle(RIGHT + 10, y, WIDHT, HEIGHT));
			final AutoShape conn = new AutoShape(ShapeTypes.BentConnector2, pomBox);
			conn.setEscherProperty((short) 4, 5898240);
			conn.setEscherProperty((short) 328, 187200);
			conn.setEscherProperty((short) 447, 1048576);
			conn.setEscherProperty((short) 448, 134217729);
			conn.setEscherProperty((short) 465, 1);
			conn.setEscherProperty((short) 511, 524296);
			conn.setEscherProperty((short) 513, 134217730);
			conn.setEscherProperty((short) 771, 1);
			conn.setAnchor(new Rectangle(pomBox.getAnchor().x + RIGHT, pomBox.getAnchor().y + pomBox.getAnchor().height, -RIGHT, y - (HEIGHT / 2)));
			conn.setLineWidth(0.75d);
			slide.addShape(conn);
		}
	}

	private TextBox addBox(final Dependency dependency) {
		if (dependency == null) {
			return null;
		}
		final TextBox txtBox = new TextBox();
		txtBox.setText(dependency.getGroupId() + "\n" + dependency.getArtifactId() + "\n" + dependency.getVersion());
		txtBox.setVerticalAlignment(TextShape.AnchorMiddleCentered);
		txtBox.setLineWidth(1d);
		txtBox.setLineColor(Color.BLACK);
		txtBox.setFillColor(Color.CYAN);
		if ("test".equals(dependency.getScope())){
			txtBox.setFillColor(new Color(187, 224, 227));
			txtBox.setLineStyle(Line.LINE_SIMPLE);
			txtBox.setLineDashing(Line.PEN_DASHDOT);
		}
		txtBox.getTextRun().getRichTextRuns()[0].setFontColor(Color.WHITE);
		txtBox.getTextRun().getRichTextRuns()[0].setFontSize(12);
		txtBox.getTextRun().getRichTextRuns()[0].setAlignment(TextBox.AlignCenter);
		slide.addShape(txtBox);

		return txtBox;
	}

	private TextBox addBox(final MavenProject project) {
		if (project == null) {
			return null;
		}
		final TextBox txtBox = new TextBox();
		txtBox.setText(project.getGroupId() + "\n" + project.getArtifactId());
		txtBox.setLineWidth(1d);
		txtBox.setLineColor(Color.BLACK);
		txtBox.setFillColor(Color.BLUE);
		txtBox.getTextRun().getRichTextRuns()[0].setFontColor(Color.WHITE);
		txtBox.getTextRun().getRichTextRuns()[0].setFontSize(12);
		txtBox.getTextRun().getRichTextRuns()[0].setAlignment(TextBox.AlignCenter);
		slide.addShape(txtBox);
		return txtBox;
	}

}
